<!--
 * @Descripttion: 考题题库操作模态框
 * @Author: wind-lc
 * @version: 1.0
 * @Date: 2021-05-14 14:34:28
 * @LastEditTime: 2021-05-19 20:33:14
 * @FilePath: \cscec-pms-admin\src\views\partyMasses\partyStudyInfo\questionBank\components\OperateForm.vue
 * @param {Boolean} visible 模态框显示
 * @param {Object} data 模态框数据
 * @return {Event} refresh 需要刷新外部列表事件
 * @example <operate-form :visible.sync="operateVisible" :data="operateData"></operate-form>
-->
<template>
  <a-modal
    :title="title"
    :visible="visible"
    destroy-on-close
    :width="1200"
    @cancel="handleClose"
  >
    <!-- 表单 -->
    <a-form-model
      ref="form"
      v-loading="loading"
      :rules="rules"
      :model="form"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    >
      <a-row :gutter="16">
        <a-col :span="8">
          <a-form-model-item
            label="试题分类"
            prop="examTypeId"
          >
            <a-select
              v-model="form.examTypeId"
              placeholder="请选择"
              show-search
              option-filter-prop="children"
              :filter-option="filterOption"
              :disabled="data.type==='detail'"
            >
              <a-select-option
                v-for="{value,label} in list.examTypeId"
                :key="value"
                :value="value"
              >
                {{ label }}
              </a-select-option>
            </a-select>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item
            label="试题类型"
            prop="type"
          >
            <selector
              v-model="form.type"
              select-type="27"
              placeholder="请选择"
              url-type="union"
              value-name="code"
              :disabled="data.type==='detail'"
            />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item
            label="考题分数"
            prop="score"
          >
            <base-input-number
              v-model="form.score"
              placeholder="请输入"
              :disabled="data.type==='detail'"
            />
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item
            label="试题内容"
            prop="content"
          >
            <base-textarea
              v-model="form.content"
              placeholder="请输入"
              :disabled="data.type==='detail'"
            />
          </a-form-model-item>
        </a-col>
        <a-col
          v-if="!data.notype"
          :span="8"
        >
          <a-form-model-item
            label="状态"
            prop="state"
          >
            <a-select
              v-model="form.state"
              placeholder="请选择"
              :disabled="data.type==='detail'"
            >
              <a-select-option
                v-for="{value,name} in list.state"
                :key="value"
                :value="value"
              >
                {{ name }}
              </a-select-option>
            </a-select>
          </a-form-model-item>
        </a-col>
      </a-row>
      <!-- 新增选项内容 -->
      <div v-if="form.type === '0' || form.type === '1'">
        <!-- 表格操作 -->
        <div class="table-operator">
          <a-button
            v-if="data.type!=='detail'"
            type="primary"
            icon="plus"
            @click="handleAdd"
          >
            新增选项内容
          </a-button>
        </div>
        <!-- 表格操作 -->
        <!-- 表格 -->
        <a-radio-group
          v-model="isCorrect['0']"
          name="a"
          class="table-wrapper"
        >
          <a-checkbox-group
            v-model="isCorrect['1']"
            name="a"
          >
            <s-table
              ref="table"
              size="default"
              row-key="id"
              :columns="dynamicColumns"
              :data="loadData"
              :show-pagination="false"
              :scroll="{ y: 200 }"
            >
              <span
                slot="c"
                slot-scope="text,record"
              >
                <base-input
                  v-model="record.c"
                  placeholder="请输入"
                  :disabled="data.type==='detail'"
                />
              </span>
              <span
                slot="a"
                slot-scope="text,record"
              >
                <a-radio
                  v-if="form.type === '0'"
                  :value="record.o"
                  :disabled="data.type==='detail'"
                />
                <a-checkbox
                  v-if="form.type === '1'"
                  :value="record.o"
                  :disabled="data.type==='detail'"
                />
              </span>
              <span
                slot="operator"
                slot-scope="text,record,index"
              >
                <template>
                  <a @click="handleDelete(index)">删除</a>
                </template>
              </span>
            </s-table>
          </a-checkbox-group>
        </a-radio-group>
        <!-- 表格 -->
      </div>
      <!-- 新增选项内容 -->
      <!-- 判断题答案 -->
      <a-row
        v-else-if="form.type === '2'"
        :gutter="16"
      >
        <a-col :span="8">
          <a-form-model-item
            label="正确答案"
            prop="judge"
          >
            <a-radio-group
              v-model="form.judge"
              :disabled="data.type==='detail'"
            >
              <a-radio :value="1">
                对
              </a-radio>
              <a-radio :value="0">
                错
              </a-radio>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
      </a-row>
      <!-- 判断题答案 -->
    </a-form-model>
    <!-- 表单 -->
    <!-- 模态框按钮 -->
    <template slot="footer">
      <a-button @click="handleClose">
        取消
      </a-button>
      <a-button
        v-if="data.type!=='detail'"
        type="primary"
        :loading="saveLoading"
        @click="handleSave"
      >
        提交
      </a-button>
    </template>
    <!-- 模态框按钮 -->
  </a-modal>
</template>
<script>
import { STable } from '@/components'
import Selector from '@/components/Select/Selector'
import { insertSelective, updateByPrimaryKeySelective } from '@/api/partyMasses/partyStudyInfo/questionBank'
export default {
  name:'a'+ Date.now(),
  // name: 'OperateForm',
  components: {
    STable,
    Selector
  },
  props: {
    // 模态框显示
    visible: {
      type: Boolean,
      require: true
    },
    // 模态框数据
    data: {
      type: Object,
      require: true
    }
  },
  data() {
    return {
      // 标题
      title: '',
      // 页面loading
      loading: false,
      // 表单
      form: {
        examTypeId: void 0,
        score: void 0,
        content: void 0,
        state: void 0,
        type: void 0
      },
      // 表单布局
      labelCol: { span: 4 },
      wrapperCol: { span: 20 },
      // 表单校验
      rules: {
        examTypeId: [
          {
            required: true,
            message: '请选择试题分类',
            trigger: 'change'
          }
        ],
        type: [
          {
            required: true,
            message: '请选择试题类型',
            trigger: 'change'
          }
        ],
        score: [
          {
            required: true,
            message: '请输入考题分数',
            trigger: 'change'
          }
        ],
        content: [
          {
            required: true,
            message: '请输入试题内容',
            trigger: 'change'
          }
        ],
        state: [
          {
            required: true,
            message: '请选择状态',
            trigger: 'change'
          }
        ],
        judge: [
          {
            required: true,
            message: '请选择正确答案',
            trigger: 'change'
          }
        ]
      },
      // 表头
      columns: [
        {
          title: '选项',
          dataIndex: 'o',
          key: 'o',
          width: '120px',
          align: 'center'
        },
        {
          title: '选项内容',
          dataIndex: 'c',
          key: 'c',
          scopedSlots: { customRender: 'c' }
        },
        {
          title: '正确与否',
          dataIndex: 'a',
          key: 'a',
          width: '120px',
          align: 'center',
          scopedSlots: { customRender: 'a' }
        },
        {
          title: '操作',
          dataIndex: 'operator',
          width: '100px',
          scopedSlots: { customRender: 'operator' }
        }
      ],
      dynamicColumns: [],
      // 提交loading
      saveLoading: false,
      // 依赖数据
      list: {},
      // 新增选项列表
      option: [],
      // 选项正确值
      isCorrect: {
        0: void 0,
        1: []
      }
    }
  },
  watch: {
    // 监听显示弹窗写入数据
    visible: {
      handler(newV, oldV) {
        if (newV) {
          try {
                      this.loading = true
          this.list = this.data.list
          switch (this.data.type) {
            case 'add':
              this.title = '新增考题'
              this.dynamicColumns = this.columns
              this.form = Object.assign({}, this.form, {
                state: 1,
                type: '0'
              })
              break
            case 'edit':
              this.title = '编辑考题'
              this.dynamicColumns = this.columns
              Object.keys(this.form).forEach((el) => {
                // 数据字典是number接口是string
                if (el === 'type') {
                  this.form[el] = this.data.record[el] + ''
                } else {
                  this.form[el] =
                    typeof this.data.record[el] === 'number'
                      ? this.data.record[el]
                      : this.data.record[el] || this.form[el]
                }
              })
              this.option = this.data.record.options.map((el) => {
                const item = JSON.parse(JSON.stringify(el))
                item.id = el.o
                return item
              })
              if (this.form.type === '0') {
                this.isCorrect['0'] = this.option.find((el) => el.a === 1).o
              }
              if (this.form.type === '1') {
                const arr = []
                this.option.forEach((el) => {
                  if (el.a === 1) {
                    arr.push(el.o)
                  }
                })
                this.isCorrect['1'] = arr
              }
              break
            case 'detail':
              this.title = '查看考题'
              let cl = [].concat(this.columns)
              cl.pop()
              this.dynamicColumns = cl
              Object.keys(this.form).forEach((el) => {
                // 数据字典是number接口是string
                if (el === 'type') {
                  this.form[el] = this.data.record[el] + ''
                } else {
                  this.form[el] =
                    typeof this.data.record[el] === 'number'
                      ? this.data.record[el]
                      : this.data.record[el] || this.form[el]
                }
              })
              this.option = this.data.record.options?.map((el) => {
                const item = JSON.parse(JSON.stringify(el))
                item.id = el.o
                return item
              })
              if (this.form.type === '0') {
                this.isCorrect['0'] = this.option.find((el) => el.a === 1).o
              }
              if (this.form.type === '1') {
                const arr = []
                this.option.forEach((el) => {
                  if (el.a === 1) {
                    arr.push(el.o)
                  }
                })
                this.isCorrect['1'] = arr
              }
              break
          }
          } catch(e) {
            console.error(e)
          }
          this.loading = false
        }
      }
    }
  },
  methods: {
    /**
     * @description: 关闭模态框
     * @param {Void}
     * @return {Void}
     */
    handleClose() {
      this.form = {
        examTypeId: void 0,
        type: void 0,
        score: void 0,
        content: void 0,
        state: void 0,
        judge: void 0
      }
      this.option = []
      this.isCorrect = {
        0: void 0,
        1: []
      }
      this.$refs.form.resetFields()
      this.$emit('update:visible', false)
    },
    /**
     * @description: 试题分类搜索
     * @param {String} input
     * @param {Object} option
     * @return {Boolean} 是否满足搜索条件
     */
    filterOption(input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    /**
     * @description: 表格数据加载方法
     * @param {Object} parameter 分页信息
     * @return {Promise} 接口Promise
     */
    async loadData() {
      return Promise.resolve({
        data: this.option
      })
    },
    /**
     * @description: 字母递增
     * @param {String} begin 起始字母(大小写均可，默认大写A)
     * @return {String} 递增后的字母
     */
    letterAscending(begin = 'A') {
      if (begin && typeof begin === 'string') {
        let index = begin.charCodeAt()
        const up = index >= 65 && index < 90
        const lo = index >= 97 && index < 122
        if (up !== lo) {
          return String.fromCharCode(index + 1)
        } else {
          console.log('需要字母')
        }
      } else {
        console.log('需要字母')
      }
    },
    /**
     * @description: 新增选项内容
     * @param {Void}
     * @return {Void}
     */
    handleAdd() {
      const lg = this.option.length
      const str = lg === 0 ? 'A' : this.letterAscending(this.option[lg - 1].o)
      this.option.push({
        id: lg + '-' + new Date().getTime(),
        o: str,
        c: '',
        a: 0
      })
    },
    /**
     * @description: 删除
     * @param {Object} record 当前行数据
     * @return {Void}
     */
    handleDelete(index) {
      this.$confirm({
        title: '温馨提示',
        content: '确定是否删除数据？',
        okText: '确认',
        okType: 'danger',
        cancelText: '取消',
        onOk: () => {
          this.option.splice(index, 1)
          this.option.forEach((el, i) => {
            el.o = i === 0 ? 'A' : this.letterAscending(this.option[i - 1].o)
          })
        }
      })
    },
    /**
     * @description: 选项必填
     * @param {Void}
     * @return {Boolean} 是否通过
     */
    required() {
      return this.option.every((el) => el.c !== '')
    },
    /**
     * @description: 不能重复
     * @param {Void}
     * @return {Boolean} 是否通过
     */
    noRepetition() {
      return new Set(this.option.map((el) => el.c)).size === this.option.length
    },
    /**
     * @description: 提交
     * @param {Void}
     * @return {Void}
     */
    handleSave() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          const { examTypeId, type, score, content, state, judge } = this.form
          switch (type) {
            case '0':
              // 单选题
              if (this.option.length > 1) {
                if (this.option.map((el) => el.o).includes(this.isCorrect[type])) {
                  if (this.required()) {
                    if (this.noRepetition()) {
                      this.$confirm({
                        title: '温馨提示',
                        content: '确定是否提交数据？',
                        okText: '确认',
                        okType: 'danger',
                        cancelText: '取消',
                        onOk: () => {
                          const options = this.option.map((el) => {
                            const item = JSON.parse(JSON.stringify(el))
                            if (item.o === this.isCorrect[type]) {
                              item.a = 1
                            } else {
                              item.a = 0
                            }
                            return item
                          })
                          this.saveLoading = true
                          if (this.data.type === 'add') {
                            // 新增
                            this.insert({
                              examTypeId,
                              type,
                              score,
                              content,
                              state,
                              options
                            })
                          } else {
                            // 编辑
                            this.update({
                              id: this.data.record.id,
                              examTypeId,
                              type,
                              score,
                              content,
                              state,
                              options
                            })
                          }
                        }
                      })
                    } else {
                      this.$message.error('选项内容有重复')
                    }
                  } else {
                    this.$message.error('请输入选项内容')
                  }
                } else {
                  this.$message.error('请选择正确答案')
                }
              } else {
                this.$message.error('需要至少2个选项内容')
              }
              break
            case '1':
              //多选题
              if (this.option.length > 1) {
                if (this.isCorrect[type].length > 0) {
                  if (this.required()) {
                    if (this.noRepetition()) {
                      this.$confirm({
                        title: '温馨提示',
                        content: '确定是否提交数据？',
                        okText: '确认',
                        okType: 'danger',
                        cancelText: '取消',
                        onOk: () => {
                          const options = this.option.map((el) => {
                            const item = JSON.parse(JSON.stringify(el))
                            if (this.isCorrect[type].includes(item.o)) {
                              item.a = 1
                            } else {
                              item.a = 0
                            }
                            return item
                          })
                          this.saveLoading = true
                          if (this.data.type === 'add') {
                            // 新增
                            this.insert({
                              examTypeId,
                              type,
                              score,
                              content,
                              state,
                              options
                            })
                          } else {
                            // 编辑
                            this.update({
                              id: this.data.record.id,
                              examTypeId,
                              type,
                              score,
                              content,
                              state,
                              options
                            })
                          }
                        }
                      })
                    } else {
                      this.$message.error('选项内容有重复')
                    }
                  } else {
                    this.$message.error('请输入选项内容')
                  }
                } else {
                  this.$message.error('请选择正确答案')
                }
              } else {
                this.$message.error('需要至少2个选项内容')
              }
              break
            case '2':
              // 判断题
              this.$confirm({
                title: '温馨提示',
                content: '确定是否提交数据？',
                okText: '确认',
                okType: 'danger',
                cancelText: '取消',
                onOk: () => {
                  this.saveLoading = true
                  if (this.data.type === 'add') {
                    // 新增
                    this.insert({
                      examTypeId,
                      type,
                      score,
                      content,
                      state,
                      judge
                    })
                  } else {
                    // 编辑
                    this.update({
                      id: this.data.record.id,
                      examTypeId,
                      type,
                      score,
                      content,
                      state,
                      judge
                    })
                  }
                }
              })
              break
            case '3':
              // 问答题
              this.$confirm({
                title: '温馨提示',
                content: '确定是否提交数据？',
                okText: '确认',
                okType: 'danger',
                cancelText: '取消',
                onOk: () => {
                  this.saveLoading = true
                  if (this.data.type === 'add') {
                    // 新增
                    this.insert({
                      examTypeId,
                      type,
                      score,
                      content,
                      state
                    })
                  } else {
                    // 编辑
                    this.update({
                      id: this.data.record.id,
                      examTypeId,
                      type,
                      score,
                      content,
                      state
                    })
                  }
                }
              })
              break
          }
        }
      })
    },
    /**
     * @description: 新增
     * @param {Object} data 接口参数
     * @return {void}
     */
    insert(data) {
      insertSelective(data)
        .then(({ code }) => {
          if (code === this.SUCCESS_CODE) {
            this.$message.success('新增成功')
            this.handleClose()
            this.$emit('refresh', true)
          } else {
            this.$message.error('新增失败')
          }
        })
        .catch((error) => {
          console.log(error)
          this.$message.error('新增失败！')
        })
        .finally(() => {
          this.saveLoading = false
        })
    },
    /**
     * @description: 编辑
     * @param {Object} data 接口参数
     * @return {void}
     */
    update(data) {
      updateByPrimaryKeySelective(data)
        .then(({ code }) => {
          if (code === this.SUCCESS_CODE) {
            this.$message.success('编辑成功')
            this.handleClose()
            this.$emit('refresh', true)
          } else {
            this.$message.error('编辑失败')
          }
        })
        .catch((error) => {
          console.log(error)
          this.$message.error('编辑失败！')
        })
        .finally(() => {
          this.saveLoading = false
        })
    }
  }
}
</script>
<style lang="less" scoped>
.table-wrapper {
  width: 100%;
}
</style>